package com.netdimensions.confluence.plugins;

import com.atlassian.confluence.pages.PageManager;
import com.atlassian.confluence.spaces.SpaceManager;
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal;
import com.atlassian.renderer.RenderContext;
import com.atlassian.renderer.v2.RenderMode;
import com.atlassian.renderer.v2.macro.BaseMacro;
import com.atlassian.renderer.v2.macro.MacroException;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
import java.io.IOException;
import java.io.InputStream;
import java.util.AbstractList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

public abstract class EkpMacro extends BaseMacro {
    protected EkpMacro() {
    }

    public final boolean isInline() {
        return false;
    }

    public final boolean hasBody() {
        return false;
    }

    public final RenderMode getBodyRenderMode() {
        return RenderMode.NO_RENDER;
    }

    public final String execute(final Map params, final String body, final RenderContext renderContext)
            throws MacroException {
        final Config config = Config.INSTANCE;
        final GetMethod method = new GetMethod(config.baseUrl + "api/" + url(params));
        try {
            final HttpClient client = new HttpClient();
            client.getParams().setAuthenticationPreemptive(true);
            client.getState().setCredentials(AuthScope.ANY, new UsernamePasswordCredentials(config.userId, config.password));
            client.executeMethod(method);
            final InputStream stream = method.getResponseBodyAsStream();
            try {
                return html(DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(stream).getDocumentElement());
            } catch (final SAXException e) {
                throw new MacroException(e);
            } catch (final ParserConfigurationException e) {
                throw new MacroException(e);
            } finally {
                stream.close();
            }
        } catch (final IOException e) {
            throw new MacroException(e);
        } finally {
            method.releaseConnection();
        }
    }

    protected abstract String html(Element root);

    protected abstract String url(Map params);
}